package edu.purdue.touch.piccolo.event;

import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;

import edu.purdue.touch.Status;
import edu.purdue.touch.TouchEventHandler;
import edu.umd.cs.piccolo.PNode;
import edu.umd.cs.piccolo.util.PBounds;

import TUIO.TuioCursor;
import TUIO.TuioObject;
import TUIO.TuioTime;

public class PBasicTouchEventListener implements PTouchListener {


	
	protected TuioCursor lastCursor;
	
	public ArrayList<TuioCursor> cursorIDs = new ArrayList<TuioCursor>();
	public TouchEventHandler eventhandler = new TouchEventHandler();
	
	public PBasicTouchEventListener() {

	}
	
	@Override
	public void TouchEventOccurred(TuioTime ttime) {
		
		
		if (eventhandler.current_status == Status.WAIT) {
			runWait();
		}
		
		eventhandler.refresh(ttime);	
		
		///////////////////////////////////////////////////////////////
		
		
		
		if( eventhandler.current_status == Status.DRAG ){
			runDragged();
		}
		if( eventhandler.current_status == Status.SELECT ){
			runSelected();
		}
					
		if( eventhandler.current_status == Status.HOVERING ){
			runHovered();			
		}
		if( eventhandler.current_status == Status.ROTATE ){
			runRotated();
		}
		//if (eventhandler.current_status != Status.INITIAL)
		//	System.out.println("ID :" + this.hashCode() +  " Status : " + eventhandler.current_status );
		
		runRefresh(ttime);
	}

	@Override
	public void TouchaddEventOccurred(TuioCursor tcur) {
		// TODO Auto-generated method stub
		eventhandler.add(tcur);
		cursorIDs.add(tcur);
	}

	@Override
	public void TouchremoveEventOccurred(TuioCursor tcur) {
		// TODO Auto-generated method stub\
		if(cursorIDs.contains(tcur))
		{
			eventhandler.remove(tcur);
			cursorIDs.remove(tcur);
			lastCursor = tcur;
		}
		
		if( eventhandler.current_status == Status.TAP )
		{			
			runTapped();
			eventhandler.current_status = Status.INITIAL;
		}
		
		if (cursorIDs.size()==0)
		{
			done();
		}
	}

	@Override
	public void TouchupdateEventOccurred(TuioCursor tcur) {
		// TODO Auto-generated method stub
		eventhandler.update(tcur);
	}
	
	private void runWait() {
		if(cursorIDs.size() >=2 ) {
			TuioCursor tcursor1 = cursorIDs.get(0);
			TuioCursor tcursor2 = cursorIDs.get(1);
			
			waited(tcursor1,tcursor2);	
		}
	}
	
	protected void runTapped() {
		if ( lastCursor != null ) {
			tapped(lastCursor);
		}		
	}
	
	private void runRotated() {
		if (cursorIDs.size() >= 2) {		
			TuioCursor tcursor1 = cursorIDs.get(0);
			TuioCursor tcursor2 = cursorIDs.get(1);
			
			rotated(tcursor1,tcursor2);	
		}	
	}

	private void runHovered() {
		if (true) { // if blob is touching on the border
			if(cursorIDs.size() == 1) {
				TuioCursor tcursor1 = cursorIDs.get(0);
				hovered(tcursor1);
			}
		}
	}

	private void runSelected() {
		// TODO Auto-generated method stub
		if(cursorIDs.size() >= 2) {		
			TuioCursor tcursor1 = cursorIDs.get(0);
			TuioCursor tcursor2 = cursorIDs.get(1);
			selected(tcursor1, tcursor2);
		}
	}

	private void runDragged() {
		if(cursorIDs.size() >= 2) {	
			TuioCursor tcursor1 = cursorIDs.get(0);
			TuioCursor tcursor2 = cursorIDs.get(1);
			dragged(tcursor1, tcursor2);
		}
	}
	
	public boolean contains (TuioCursor tcur, PBounds p) {
    	if ( tcur.getScreenX(PTouchEventManager.getInstance().screenX) > p.getX() && tcur.getScreenX(PTouchEventManager.getInstance().screenX) < ( p.getX()+p.getWidth() ) &&
				tcur.getScreenY(PTouchEventManager.getInstance().screenY) > p.getY() && tcur.getScreenY(PTouchEventManager.getInstance().screenY) < ( p.getY()+p.getHeight() ))
			return true;
		else
			return false;
    }
	
	public boolean contains(TuioCursor tcur, PNode node) {
		AffineTransform at = node.getTransform();
		Shape s = at.createTransformedShape(new Rectangle2D.Double(0,0,node.getWidth(),node.getHeight()));
		return s.contains(tcur.getScreenX(PTouchEventManager.getInstance().screenX),tcur.getScreenY(PTouchEventManager.getInstance().screenY));
	}
	
	public boolean contains(TuioCursor tcur, Rectangle bound, AffineTransform at) {
		Shape s = at.createTransformedShape(new Rectangle2D.Double(bound.getX(),bound.getY(),bound.getWidth(),bound.getHeight()));
		return s.contains(tcur.getScreenX(PTouchEventManager.getInstance().screenX),tcur.getScreenY(PTouchEventManager.getInstance().screenY));
	}
	
	@Override
	public void ObjectaddEventOccurred(TuioObject tobj) {
		objectAdded(tobj);		
	}

	@Override
	public void ObjectremoveEventOccurred(TuioObject tobj) {
		objectRemoved(tobj);	
	}

	@Override
	public void ObjectupdateEventOccurred(TuioObject tobj) {
		objectUpdated(tobj);		
	};
	
	public void hovered(TuioCursor tcur) {}; //Might be better to pass tcursor
	public void tapped(TuioCursor tcur) {};
	public void dragged(TuioCursor tcur1, TuioCursor tcur2) {};
	public void rotated(TuioCursor tcur1, TuioCursor tcur2) {};
	public void selected(TuioCursor tcur1, TuioCursor tcur2) {};
	public void waited(TuioCursor tcur1, TuioCursor tcur2) {};
	public void runRefresh(TuioTime ttime) {};
	public void done() {}
	public void objectAdded(TuioObject tobj) {};
	public void objectRemoved(TuioObject tobj) {};
	public void objectUpdated(TuioObject tobj) {};
}
